package com.termux.ui.ide

import android.Manifest
import android.app.AlertDialog
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
import android.view.View
import android.view.inputmethod.InputMethodManager
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.GravityCompat
import com.google.android.material.tabs.TabLayout
import com.idea.editor.TextEditor
import com.termux.R
import com.termux.databinding.ActivityMainBinding
import com.termux.fileview.FileView
import com.termux.frontend.config.NeoTermPath
import com.termux.frontend.logging.NLog
import com.termux.project.ProjectPresenter
import com.termux.ui.ide.tab.ConfigTab
import com.termux.ui.ide.tab.EditTab
import com.termux.ui.ide.tab.FileTab
import com.termux.ui.settings.SettingActivity
import com.termux.ui.term.NeoTermActivity
import com.termux.utils.CommandUtil
import com.termux.utils.LibUtil
import com.termux.utils.PermissionUtil.applyPermission
import com.termux.utils.PermissionUtil.hasPermission
import org.apache.commons.io.FileUtils
import java.io.File


open class MainActivity : AppCompatActivity() {


    fun closeInputMethod(view: View?) {
        val inputMethodManager: InputMethodManager =
            getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
        inputMethodManager.hideSoftInputFromWindow(
            view?.windowToken,
            InputMethodManager.HIDE_NOT_ALWAYS
        )
    }


    private lateinit var projectPresenter: ProjectPresenter
    lateinit var binding: ActivityMainBinding
    lateinit var tabList: ArrayList<FileTab>
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)
        setSupportActionBar(binding.contentView.toolbar)
        tabList = arrayListOf()

        checkPermission()
        initEvent();

        projectPresenter = ProjectPresenter(this)
        projectPresenter.openProject()
    }

    private fun checkPermission() {
        val permissions = arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE)
        for (perm in permissions) {
            if (!hasPermission(this, perm)) {
                applyPermission(this, perm)
            }
        }
    }

    override fun onBackPressed() {
        if (binding.mainDrawer.isDrawerOpen(GravityCompat.START)) {
            binding.mainDrawer.closeDrawer(GravityCompat.START)
        } else
            finish()
    }

    private fun TabLayout.Tab.getFileTab(): FileTab {
        return tag as FileTab
    }

    fun TabLayout.Tab.onSelect() {
        binding.contentView.containerView.run {
            removeAllViews()
            getFileTab().onSelected()
            addView(getFileTab().contentView)
        }
    }


    private fun initEvent() {
        with(binding.contentView.fileTabs.tabLayout) {
            tabGravity = TabLayout.GRAVITY_FILL
            tabMode = TabLayout.MODE_SCROLLABLE

            addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener {
                override fun onTabReselected(tab: TabLayout.Tab?) {
                    tab?.let {
                        val fileTab = it.tag as FileTab
                        if (fileTab.changed) {
                            AlertDialog.Builder(this@MainActivity).setTitle("提示")
                                .setMessage("是否保存文件" + fileTab.file?.name.toString() + "？")
                                .setNegativeButton(
                                    "不保存"
                                ) { dialog, _ -> dialog.dismiss() }
                                .setPositiveButton(
                                    "保存"
                                ) { dialog, _ ->
                                    dialog.dismiss()
                                    fileTab.save()
                                    projectPresenter.updateProject()
                                }.setCancelable(false).create().show()
                        }
                        fileTab.onClose()
                        tabList.remove(fileTab)
                        binding.contentView.fileTabs.tabLayout.removeTab(it)
                        binding.contentView.containerView.removeAllViews()
                    }
                }

                override fun onTabUnselected(tab: TabLayout.Tab?) {
                }

                override fun onTabSelected(tab: TabLayout.Tab?) {
                    tab?.onSelect()
                }
            })
        }

        binding.fileView.setFileListener(object : FileView.FileListener {
            val tabLayout = binding.contentView.fileTabs.tabLayout
            override fun onOpen(file: File?) {
                openFile(file)
            }

            override fun onRename(oldFile: File?, newFile: File?) {
                val fileTab = FileTab(oldFile)
                if (tabList.contains(fileTab)) {
                    tabList.remove(fileTab)
                }
                runOnUiThread {
                    ->
                    tabLayout.run {
                        for (index in 0..tabCount) {
                            val tab =
                                if (getTabAt(index)?.tag != null) getTabAt(index)?.tag as FileTab else null
                            if (fileTab == tab) {
                                binding.contentView.containerView.run {
                                    removeAllViews()
                                }
                                removeTabAt(index)
                            }
                        }
                    }
                }
            }

            override fun onCut(oldFile: File?, newFile: File?) {
                val fileTab = FileTab(oldFile)
                if (tabList.contains(fileTab)) {
                    tabList.remove(fileTab)
                }
                runOnUiThread {
                    ->
                    tabLayout.run {
                        for (index in 0..tabCount) {
                            val tab =
                                if (getTabAt(index)?.tag != null) getTabAt(index)?.tag as FileTab else null
                            if (fileTab == tab) {
                                binding.contentView.containerView.run {
                                    removeAllViews()
                                }
                                removeTabAt(index)
                            }
                        }
                    }
                }
            }

            override fun onDelete(file: File?) {
                val fileTab = FileTab(file)
                if (tabList.contains(fileTab)) {
                    tabList.remove(fileTab)
                }
                runOnUiThread {
                    ->
                    tabLayout.run {
                        for (index in 0..tabCount) {
                            val tab =
                                if (getTabAt(index)?.tag != null) getTabAt(index)?.tag as FileTab else null
                            if (fileTab == tab) {
                                binding.contentView.containerView.run {
                                    removeAllViews()
                                }
                                removeTabAt(index)
                            }
                        }
                    }
                }
            }

            override fun onAdd(file: File?) {

            }

        })
    }

    fun openFile(file: File?) {
        binding.contentView.fileTabs.tabLayout.run {
            val tab = newTab()
            val fileTab = file?.let {
                if (file.endsWith("config.json")) {
                    val configTab = ConfigTab(it)
                    val view = layoutInflater.inflate(R.layout.config_view, null, false)
                    configTab.contentView = view
                    projectPresenter.openProject(it)
                    configTab
                } else {
                    val editTab = EditTab(it)
                    val textEditor = TextEditor(this@MainActivity)
                    textEditor.setText(FileUtils.readFileToString(file, "utf-8"))
                    editTab.contentView = textEditor
                    editTab
                }
            }
            if (!tabList.contains(fileTab as FileTab)) {
                fileTab.let { tabList.add(it) }
                tab.tag = fileTab
                tab.text = file.name
                addTab(tab, true)
            }
        }
    }

    override fun onCreateOptionsMenu(menu: Menu?): Boolean {
        menuInflater.inflate(R.menu.main, menu);
        return true
    }

    open fun getViewBinding(): ActivityMainBinding {
        return binding
    }

    private fun saveFile() {
        tabList.run {
            for (tab in this) {
                if (tab.changed) tab.save()
            }
        }
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        when (item.itemId) {
            R.id.action_compile -> {
                saveFile()
                projectPresenter.compileProject()
            }
            R.id.action_run -> projectPresenter.runProject()
            R.id.action_save -> saveFile()
            R.id.action_settings -> {
                startActivity(Intent(this, SettingActivity::class.java))
            }
            R.id.action_terminal -> {
                val intent = Intent(this, NeoTermActivity::class.java)
                intent.putExtra("work_dir", projectPresenter.getOpenDir())
                startActivity(intent)
            }
            R.id.code_format -> {
                //TODO format code
                binding.contentView.fileTabs.tabLayout.run {
                    val fileTab = getTabAt(selectedTabPosition)?.getFileTab()
                    if (fileTab?.contentView is TextEditor) {
                        NLog.i("idea","editor view")
                        CommandUtil.run("${NeoTermPath.USR_PATH}/bin/clang-format -style=LLVM -i ${fileTab.file?.absolutePath}")
                        (fileTab.contentView as TextEditor).setText(FileUtils.readFileToString(fileTab.file, "utf-8"))
                    }
                }
            }
        }
        return super.onOptionsItemSelected(item)
    }
}
